﻿using Sustainalytics.Entities.RiskRatings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sustainalytics.RiskRatings.Service.Models
{   
    public class MeiDto
    {
        public int ExternalId { get; set; }

        public string Name { get; set; }

        public string Type { get; set; }

        public bool? IsMain { get; set; }

        public double? FinalWeight { get; set; }

        public PerformanceDto Exposure { get; set; }

        public PerformanceDto Management { get; set; }

        public PerformanceDto Unmanaged { get; set; }

        public PerformanceDto SubIndustryExposure { get; set; }
        public PerformanceDto ExcessExposure { get; set; }

        public PerformanceDto ManageableRiskFactor { get; set; }

        public IEnumerable<EventIndicatorDto> Events { get; set; }

        public MeiDto(RiskRatingMaterialEsgIssueBase issue, List<RiskRatingMeiSubPeerGroupAverage> subPeerAverage, bool withEvents = false, List<int> allowedEventCategories = null)
        {
            ExternalId = issue.ExternalId;
            Name = issue.Name;
            Type = issue.Type.ToString();
            IsMain = issue.IsMain.Value;
            FinalWeight = issue.FinalWeight?.Value;

            Exposure = new PerformanceDto(issue.ExternalId, issue.ManagementRisk.Exposure, subPeerAverage, x => x.ExposureAverage);
            Management = new PerformanceDto(issue.ExternalId, issue.ManagementRisk.Management, subPeerAverage, x => x.ManagementRiskAverage);
            Unmanaged = new PerformanceDto(issue.ExternalId, issue.ManagementRisk.UnmanagedRisk, subPeerAverage, x => x.UnmanagedRiskAverage, issue.Cluster);
            ExcessExposure = new PerformanceDto(issue.ExternalId, issue.ExcessExposure, subPeerAverage, x => x.ExcessExposureAverage);
            SubIndustryExposure = new PerformanceDto(issue.ExternalId, issue.SubIndustryExposureScore, subPeerAverage, x => x.SubIndustryExposureAverage);
            ManageableRiskFactor = new PerformanceDto(issue.ExternalId, issue.ManageableRiskFactorPercentile, subPeerAverage, x => x.ManageableRiskFactorAverage);

            if (withEvents)
                Events = issue.Indicators
                    .Where(x => x.IndicatorType == IndicatorType.EventIndicator && (allowedEventCategories == null || allowedEventCategories.Contains(x.AnswerCategory.Value)))
                    .Select(x => new EventIndicatorDto(x));
        }
    }


    public class PerformanceDto
    {
        public double Value { get; set; }

        public double Average { get; set; }

        public string ClusterName { get; set; }

        public PerformanceDto(
           int issueId,
           Timestamped<double> performance,
           List<RiskRatingMeiSubPeerGroupAverage> subPeerAverage,
           Func<RiskRatingMeiSubPeerGroupAverage, double> selector,
           RiskRatingCluster cluster = null)
        {
            Value = performance.Value;
            Average = subPeerAverage.Where(x => x.ExternalId == issueId).Select(selector).DefaultIfEmpty(0).FirstOrDefault();
            ClusterName = cluster?.Assessment.ToString() ?? null;
        }
    }

    public class EventIndicatorDto
    {
        public string Code { get; set; }

        public string Name { get; set; }

        public int Category { get; set; }

        public string CategoryText { get; set; }

        public EventIndicatorDto(RiskRatingIndicatorBase indicator)
        {
            Code = indicator.Code;
            Name = indicator.Name;
            Category = indicator.AnswerCategory.Value;
            CategoryText = indicator.AnswerCategoryText;
        }
    }
}
